package PrjConf

import (
	"dgo/goutils/dnet"
	"dgo/goutils/utils"
	"errors"
	"fmt"
	"gitee.com/ymofen/supervalue"
	"io/ioutil"
	"net/http"
	"os"
	"time"
)

var (
	CONFIG_CONF_API_SVR_URL string = "http://58.49.94.210:9101"
	CONFIG_CONF_APP_ID      string = "" // 读取配置的APP_ID
	CONFIG_CONF_APP_TYPE    string = "" // 读取配置的APP_TYPE
)

func readConfigFromApiSvr(apiUrl string, appid string, strType string, fileName string) (error, string) {
	exeName := utils.ExtractFileNameWithOutPathAndExt(os.Args[0])

	url := apiUrl + "/sys/conf/get?typeid=" + strType + "&appid=" + utils.EscapeUrl(appid) +
		"&file=" + utils.EscapeUrl(fileName) + "&exe=" + utils.EscapeUrl(exeName)
	resp, err := http.Get(url)
	if err != nil {
		return err, ""
	}
	defer resp.Body.Close()
	if resp.StatusCode == 404 || resp.StatusCode == 503 {
		return errors.New(fmt.Sprintf("配置中心读取(%s)出现异常:%s", url, resp.Status)), ""
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return errors.New(fmt.Sprintf("配置中心读取(%s)出现异常:%s", url, err.Error())), ""
	}
	return nil, string(body)
}

func ReadConfigFromApiSvr(appid string, strType string) (error, string) {
	return readConfigFromApiSvr(CONFIG_CONF_API_SVR_URL, appid, strType, "")
}

func parseJSON(jsonData []byte) (*wrapper.SuperValue, error) {
	defer utils.PanicHandler()
	return wrapper.NewSVFromBuf(jsonData)
}

func ReadUntilSuccByConf() *wrapper.SuperValue {
	if localConf.BoolByName("localConf", false) {
		return localConf
	}

	app_id := localConf.AsString("config_appid", "")
	if len(app_id) == 0 {
		appid_suffix := localConf.AsString("config_appid_suffix", "")
		if len(appid_suffix) == 0 {
			app_id = fmt.Sprintf("%X-0", utils.CRC24QBuf([]byte(dnet.GetFirstMacAsString())))
		} else {
			app_id = fmt.Sprintf("%X-%s", utils.CRC24QBuf([]byte(dnet.GetFirstMacAsString())), appid_suffix)
		}
	}

	apiUrl := localConf.AsString("config_api_url", "")
	if len(apiUrl) == 0 {
		apiUrl = CONFIG_CONF_API_SVR_URL
	}

	strType := localConf.AsString("config_app_type", "")
	configFile := "app.config.json"
	utils.Log.Infof("配置中心地址:%s, app_id:%s, apptype:%s, configfile:%s",
		apiUrl, app_id, strType, configFile)
	return readUntilSucc(apiUrl, app_id, strType, configFile)
}

func readUntilSucc(apiUrl string, appid string, strType string, fileName string) *wrapper.SuperValue {
	for {
		err, str := readConfigFromApiSvr(apiUrl, appid, strType, fileName)
		if err != nil {
			utils.Log.Warnf("读取配置失败, 10秒后重试, msg:%s", err.Error())
			time.Sleep(time.Second * 10)
		} else if len(str) == 0 {
			utils.Log.Warnf("读取配置失败: 10秒后重试!")
			time.Sleep(time.Second * 10)
		} else {
			conf, err := parseJSON([]byte(str))
			if err != nil {
				utils.Log.Warnf("解析配置出现异常:%s\n%s, 10秒后重试!", err.Error(), str)
				time.Sleep(time.Second * 10)
			} else if conf == nil {
				utils.Log.Warnf("解析配置出现失败\n:%s, 10秒后重试!", str)
				time.Sleep(time.Second * 10)
			}
			return conf
		}
	}
}
